package com.mybooksystem.springboot.controller;

import com.mybooksystem.springboot.config.Result;
import com.mybooksystem.springboot.pojo.student.Students;
import com.mybooksystem.springboot.service.StudentsService;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.http.HttpCookie;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 处理页面跳转的控制器。
 */
@Controller
public class PageController extends BaseController {

    @Autowired
    StudentsController studentsController;

    @Autowired
    StudentsService studentsService;

    /**
     * 请求转发到后台管理页面
     * @return
     */
//    @GetMapping("/managementSystem/{username}")
    @GetMapping("/managementSystem")
    public String management(
            HttpServletResponse response,/*@PathVariable(value = "username",required = false) String username, */
            HttpServletRequest request,
            @SessionAttribute("username")String username,   // 获取 session 中的参数。
            @SessionAttribute("loginSession")String loginSession,
            HttpSession session
    ){

        //跳转到后台管理系统
        System.out.println("跳转到后台管理系统！ ========================================= ");
        System.out.println("用户名：" + username);
//        System.out.println("登录唯一会话：" + loginSession);
//        System.out.println("super.UUID（旧） ==》 " + uuid);
//        System.out.println("登录会话与当前新会话是否相同？ ==》 " + (loginSession.equals(uuid) ));

        // 如果 UUID 相等，则说明是登录完成。登录完成之后，跳转到登录页面。
        if (loginSession.equals(uuid)){
            // 首次进入后台管理。
            if (uuid == null) {
                // 新的 UUID。
                uuid = UUID.randomUUID().toString();
            }
            // cookie 不能存放中文。
//            Cookie cookie = new Cookie("username", URLEncoder.encode("张三", StandardCharsets.UTF_8) );
            Cookie cookie  = new Cookie("username",URLEncoder.encode("张三", StandardCharsets.UTF_8));

            System.out.println("cookie.toString() = " + cookie.toString());
            System.out.println("名称：" + cookie.getName() + "。值："+cookie.getValue());


//            response.addCookie(cookie);

            response.setHeader("Cookie", ""+ cookie.getName()+"="+cookie.getValue()+"; ");
            session.setAttribute("loginSession",uuid);

            System.out.println("uuid（新） ==> " + uuid);
            System.out.println("\n\n\n");
//            System.out.println("新的UUID为：" + uuid);
//            System.out.println("新的loginSession（@SessionAttribute）为：" + loginSession);
//            System.out.println("新的loginSession（session）为：" + session.getAttribute("loginSession").toString());

            return "forward:/manageSystem/index.html";
        }
        // 不符合规则。【非法用户】
//        System.out.println("当前loginSession（@SessionAttribute）为：" + loginSession);
//        System.out.println("当前loginSession（session）为：" + session.getAttribute("loginSession").toString());
//        System.out.println("当前UUID为："+uuid);
        // 如果两个 UUID 不相等，则重定向到首页。
        return "redirect:/";

//        System.out.println("=======================================================");
//        System.out.println("session 会话：" + session.getAttribute("username"));   //当前用户信息
//        System.out.println("session loginSession = " + session.getAttribute("loginSession"));
//        System.out.println("页面的 session 地址： ==》 "+ session.toString());

        // 到达后台管理之后注销 session。
//        session.invalidate();
//        System.out.println("session 销毁之后！");

//        System.out.println("uuid ==> " + uuid);
//        System.out.println("登录会话与当前新会话是否相同？ ==》 " + (loginSession == super.uuid));
//        System.out.println("登录会话与当前新会话是否相同？ ==》 " + (loginSession.equals(super.uuid) ));

//        response.setHeader("Cookie",session.getAttribute("username").toString());
//        response.setHeader("Cookie","zhangSan");
        // 无法解决浏览器后退与前进的功能。

        //请求转发到后台管理系统。
//        return "forward:/manageSystem/index.html";
    }

    /**
     * 跳转到学生修改页面。【乱码未解决。】
     * @param studentId：要修改的学生学号。
     * @param session：把学生信息保存在该 session 中。供前端页面数据进行展示。
     * @return
     *      返回修改页面。【修改与添加使用相同的页面】
     */
    @Deprecated
//    @GetMapping("/manageSystem/studentInfoPage/{studentId}")
    public String studentInfoPage(@PathVariable("studentId") String studentId,HttpServletRequest request,HttpServletResponse response,HttpSession session){
        System.out.println("请求字符编码：" + request.getCharacterEncoding());
        System.out.println("响应字符编码：" + response.getCharacterEncoding());

        // 查询学生学号。
        if (studentsController.isStudentInfo(studentId)){
            System.out.println("学生存在");
            // 学生存在。
            Students studentInfo = studentsService.getStudentInfo(studentId);
            // 响应学生信息。
//            response.setHeader("student", Arrays.toString(String.valueOf(studentInfo).getBytes(StandardCharsets.UTF_8)));
            response.setHeader("student", String.valueOf(studentInfo));
//            session.setAttribute("student",studentInfo);
            System.out.println(studentInfo);
        }else {
            System.out.println("学生信息错误！");
        }
        // 根据学生学号获取学生的个人信息。
        // 把学生信息保存到 session 中。【保存格式为 json。【map】】


        return "forward:/manageSystem/view/user/user-add.html";
    }

    /**
     * 获取路径位置的前缀。
     * @return
     */
    @GetMapping("/getStudentsDataPrefix")
    @ResponseBody
    public Result<String> getStudentsDataPrefix(){
        // 3. 回传数据。
        return new Result<>(0,100,"成功","/managementSystem");
    }


    /**
     * 用户访问网页时，发送一个唯一id，用来判断用户。【未实现】
     * @param request：
     * @param session
     * @return
     */
    @GetMapping({"/","/index"})
    public String index(HttpServletRequest request, HttpServletResponse response, HttpSession session){
//
//        HttpCookie cookie = new HttpCookie("loginSession",UUID.randomUUID().toString());
//
//        System.out.println("cookie.getValue() = " + cookie.getValue());
//        System.out.println("cookie.toString() = " + cookie.toString());
//
//        response.setHeader("Set-Cookie",cookie.getName() +"=" + cookie.getValue());
//        request.setAttribute("Cookie",cookie.getName() +"=" + cookie.getValue());

//        System.out.println("当前会话（JSESSIONID）：" + session.getAttribute("JSESSIONID"));
        // 获取请求头信息。

        // 第一次访问页面时，从 response.getHeader("Set-Cookie") 中获取 JSESSIONID 。【需要进行 string 切片】【当这个值为null时，说明是非第一次进入。】
        // 第二次访问页面时，从 request.getSession().getAttribute("JSESSIONID") 中获取 JSESSIONID 。【第一次获取时，为null。】
        // JSESSIONID 声明周期：获取 JSESSIONID 后，会随着页面关闭而消失。

        // 同一浏览器中开启多个窗口，JSESSIONID 唯一。
        // 不同浏览器的窗口，JSESSIONID 不同。
//        Enumeration<String> headerNames = request.getHeaderNames();
//        headerNames.asIterator().forEachRemaining(System.out::println);
//
//        // 第一次访问是没有这个 JSESSIONID 。
//        // JSESSIONID 会在响应头中。
//        System.out.println(" request ==========================");
//        // 第二次访问，页面会附加上浏览器分配好的 JSESSIONID 一并传送。
//        System.out.println("当前会话（JSESSIONID）： ==> getSession() ：" + request.getSession().getAttribute("JSESSIONID"));
//        // 第一次，cookie唯一。带上 key - value。
//        System.out.println("当前会话（JSESSIONID）： ==> getHeader() ：" + request.getHeader("cookie"));
//
//
//        // 获取响应头中的所有的 key.
//        Collection<String> headerNames1 = response.getHeaderNames();
//        // 获取某个响应头中的 Set-Cookie 的值。
//        System.out.println("Set-Cookie 的值： ==》 " + response.getHeader("Set-Cookie"));
//
//        System.out.println("response ============================");
//        for (String s : headerNames1) {
//            System.out.println(s);
//        }
//
//
//        // 获取请求头中的 cookie 。
//        Cookie[] cookies = request.getCookies();
//        System.out.println("request.getCookies() =============================");
//        for (Cookie c : cookies) {
//            if (c.getName().equals("JSESSIONID")){
//                System.out.println("获取cookie的值（JSESSIONID）；" + c.getValue());
//            }
//            System.out.println("当前 cookie："  + c.getName() +" ："+ c.getValue());
//        }
//
//        System.out.println("\n\n\n");
//        Arrays.stream(cookies).iterator().forEachRemaining(System.out::println);

//        return "forward:/index.html";
//        return "forward:/signIn.html";
//        return "forward:/IndexWeb/index.html";
        return "forward:/index.html";
    }

    /**
     * 去登录页面。
     * @return
     */
    @GetMapping("/login.html")
    public String tosignIn(){
//        int i = 10/0;

        return "redirect:/signIn.html";
    }


    /**
     * loginLog 测试。
     * 登录日志信息测试。
     * @return
     */
    @Deprecated
    @GetMapping("/test")
    @ResponseBody
    public Map<String,Object> test(){

        HashMap<String, Object> map = new HashMap<>();
        map.put("count",30);
        map.put("code",0);

        //
        HashMap<String, String> map1 = new HashMap<>();
        List<Object> list = new ArrayList<>();

        map1.put("userName","张三");
        map1.put("IP","121.69.4.82");
        map1.put("status","成功");
        map1.put("creationTime","2018-12-02 07:30:52");


        HashMap<String, String> map2 = new HashMap<>();
        map1.put("userName","李四");
        map1.put("IP","121.69.4.82");
        map1.put("status","成功");
        map1.put("creationTime","2018-12-02 07:30:52");


        list.add(map1);
        list.add(map2);
        /**
         *
         * 如果报
         *      Cannot create property 'LAY_TABLE_INDEX' on string '2018-12-02 07:30:52' at String.
         * 原因：
         *      data是一个数组。而不是一个对象
         *      正确格式：     data[{}]。
         *      报错格式：     data{}。
         * 解决办法：
         *      把 map 套在 list 上。
         */


//        map.put("data",map1);
        map.put("data",list);

        return map;
    }

    @Deprecated
    @PostMapping("/test")
    @ResponseBody
    public String testPost(){
        return "数据成功请求！";
    }

    /**
     * 登出。
     * @return
     */
    @GetMapping("/logout")
//    @ResponseBody
    public String logout(HttpServletRequest request,HttpServletResponse response, HttpSession session){

        System.err.println("退出系统！");

//        response.setHeader("Cache-Control","no-cache,no-store");
//        response.setHeader("Pragma","no-cache");
//        response.setDateHeader ("Expires", -1);

        request.setAttribute("Referer","/");

        response.setHeader("Pragma","No-Cache");
        response.setHeader("Cache-Control","No-Cache");
        response.setDateHeader("Expires", 0);

        session.invalidate();

        Enumeration<String> headerNames = request.getHeaderNames();
        headerNames.asIterator().forEachRemaining(System.out::println);

        //修改请求头中的值。
        // 修改不成功.
        reflectSetparam(request,"referer","/");
        reflectSetparam(request,"Referer","/");

//        return "redirect:/signIn.html";
//        return "forward:/signIn.html";
        return "forward:/";
//        return "";
    }

    /**
     * 修改header信息，key-value键值对儿加入到header中。
     * 失效，无法修改。
     * @param request
     * @param key
     * @param value
     */
    @Deprecated
    private void reflectSetparam(HttpServletRequest request,String key,String value){
        Class<? extends HttpServletRequest> requestClass = request.getClass();
        System.out.println("request实现类="+requestClass.getName());
        try {
            Field request1 = requestClass.getDeclaredField("request");
            request1.setAccessible(true);
            Object o = request1.get(request);
            Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);
            Object o1 = coyoteRequest.get(o);
            System.out.println("coyoteRequest实现类="+o1.getClass().getName());
            Field headers = o1.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders o2 = (MimeHeaders)headers.get(o1);
            o2.addValue(key).setString(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
